package com.yituo.mjworld.mvc.action.user;

import com.yituo.mjworld.core.annotation.*;
import com.yituo.mjworld.core.exception.MyException;
import com.yituo.mjworld.core.web.core.MyHttpRequest;
import com.yituo.mjworld.core.web.core.MyHttpResponse;
import com.yituo.mjworld.core.web.core.Result;
import com.yituo.mjworld.mvc.action.IBaseAction;
import com.yituo.mjworld.mvc.entity.web.*;
import com.yituo.mjworld.mvc.form.DeleteForm;
import com.yituo.mjworld.mvc.form.support.order.QueryOrder;
import com.yituo.mjworld.mvc.service.impl.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 订单模块
 */
@Component
public class OrderAction implements IBaseAction {
  @Autowired
  UserAddressServiceImpl userAddressService;

  @Autowired
  OrderServiceImpl orderService;

  @Autowired
  ProductServiceImpl productService;

  @Autowired
  ShopCatServiceImpl shopCatService;

  @Autowired
  WxServiceImpl wxService;

  @Autowired
  UserServiceImpl userService;

  /**
   * 获取订单列表
   * <p>
   * 匿名用户无法访问!
   *
   * @param req
   * @param res
   * @throws IOException
   */
  @Override
  @Auth(admin_user = true)
  @Check(form = QueryOrder.class)
  public void getList(MyHttpRequest req, MyHttpResponse res) throws IOException {
    QueryOrder form = (QueryOrder) req.getForm();
    WebUser currentUser = req.getCurrentUser();
//    if (currentUser.getRule() == UserRole.SUPER_ADMIN) {
//      res.success(orderService.getList(form));
//    } else {
//      res.success(orderService.getListForUser(form, currentUser.getId()));
//    }
    res.success(orderService.getListForUser(form, "fd539947b99746949b2870e455bfa238"));
  }

  /**
   * 删除订单
   *
   * @param req
   * @param res
   * @throws IOException
   */
  @Override
  @Auth(admin_user = true)
  public void delete(MyHttpRequest req, MyHttpResponse res) throws IOException {
    int userType = req.getCurrentUser().getRule();
    if (userType == UserRole.SUPER_ADMIN) {
      WebUser user = req.getCurrentUser();
      String orderId = req.getParameter("orderId");
      res.success(this.orderService.deleteByUser(user.getId(), orderId));
    }
    if (userType == UserRole.SUPER_ADMIN) {
      // 查询全部用户产生的订单
      res.success(this.orderService.delete((DeleteForm) req.getForm()));
    }
  }

  /**
   * 修改或更新订单
   *
   * @param req
   * @param res
   * @throws IOException
   */
  @Ban
  @Override
  @Check(form = WebOrder.class)
  @Auth(admin_user = true)
  public void saveOrUpdate(MyHttpRequest req, MyHttpResponse res) throws IOException {
 /*   WebOrder order = JSONObject.toJavaObject(this.orderService.saveOrUpdate(req.getForm()), WebOrder.class);
    res.success(order.getOrderId());*/
  }

  /**
   * 创建订单.
   * 适合单条产品直接进行交易.
   * 比如:用户选择立即购买某件商品.
   * <p>
   * 需要校验产品ID,UserId,地址Id
   */
  @Check(form = WebOrder.class)
  public void createOrder(MyHttpRequest req, MyHttpResponse res) throws IOException {
    WebOrder order = (WebOrder) req.getForm();
    Product product = productService.getProduct(order.getProductId());
    if (product == null) {
      res.failed("产品不存在");
      return;
    }
    WebUserAddress userAddress = userAddressService.getUserAddress(order.getAddressId(), req.getCurrentUser().getId());
    if (userAddress == null) {
      res.failed("收获地址不存在!");
      return;
    }
    WxUserinfo wxUserinfo = userService.getWxUserInfo(req.getCurrentUser().getId());
    if (wxUserinfo == null) {
      res.failed("当前用户没有绑定微信信息!");
      return;
    }
    String ip = req.getRemoteAddr();
    System.out.println("client-ip:" + ip);
    Result result = orderService.validatePrice(product, order.getTemplate(), order.getBuyNum(), order.getFinalPrice(), order.getTotalPrice());
    if (!result.getResult()) {
      // 1.前端参数校验不通过
      res.setResult(result);
      return;
    }
    try {
      res.setResult(orderService.createOrder(order, product, req.getCurrentUser(), wxUserinfo.getOpenid(), ip));
    } catch (MyException e) {
      e.printStackTrace();
      res.failed("订单创建失败!");
    }
    return;
  }

  /**
   * 微信通知的回调接口
   *
   * @param req
   * @param res
   * @throws IOException
   */
  @NoToken
  public void wxPayNotify(MyHttpRequest req, MyHttpResponse res) throws IOException {
    String xmlData = getXmlData(req);
    Map<String, String> processResult = null;
    Map<String, String> params = null;

    try {
      params = WXPayUtil.xmlToMap(xmlData);
      String return_code = params.get("return_code");
      if ("SUCCESS".equals(return_code)) {
        Result rs = orderService.updatePrepayLog(params);
        if (rs.getResult()) {
          processResult = new HashMap<String, String>(16);
          processResult.put("return_code", "SUCCESS");
          processResult.put("return_msg", "OK");
          String responseText = WXPayUtil.mapToXml(processResult);
          res.getWriter().append(responseText);
          return;
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
//      processResult.put("");
    }
    processResult.put("return_code", "FAIL");
    processResult.put("return_msg", "订单更新失败");
    String responseText = null;
    try {
      responseText = WXPayUtil.mapToXml(processResult);
    } catch (Exception e) {
      e.printStackTrace();
    }
    res.getWriter().append(responseText);
    return;

  }

  /**
   * 查询订单支付结果
   *
   * @param req
   * @param res
   * @throws IOException
   */
  @NoToken
  @Rule(name = "trandNo", name_zn = "订单号", required = false)
  public void queryPayResult(MyHttpRequest req, MyHttpResponse res) throws IOException {
    System.out.println("正在查询订单");
//    String trandNo = req.getParameter("trandNo");
    String trandNo = "8c850deab7fb4ec8b6245d2c260ca361";
    TransactionLog log = orderService.getPayLog(trandNo);
    if (log == null) {
      res.failed("订单不存在");
      return;
    }
    if (log.getStatus() == WebOrder.STATUS_PAY_END) {
      res.success(log);
      return;
    }
    // 调用微信查询订单接口,查询订单是否支付成功!
//    Map<String, String> params = wxService.orderQuery(trandNo);
//    Result result = orderService.updatePrepayLog(params);
    HashMap params= new HashMap<>();
    params.put("out_trade_no",trandNo);
    Result result = orderService.updatePrepayLog(params);
    res.setResult(result);
  }

  /**
   * 获取HTTP:
   * XML数据
   *
   * @return
   */
  private String getXmlData(MyHttpRequest req) throws IOException {
    ServletInputStream sis = req.getInputStream();
    req.setCharacterEncoding("UTF-8");
    // 取HTTP请求流长度
    int size = req.getContentLength();
    // 用于缓存每次读取的数据
    byte[] buffer = new byte[size];
    // 用于存放结果的数组
    byte[] xmldataByte = new byte[size];
    int count = 0;
    int rbyte = 0;
    // 循环读取
    while (count < size) {
      // 每次实际读取长度存于rbyte中
      rbyte = sis.read(buffer);
      for (int i = 0; i < rbyte; i++) {
        xmldataByte[count + i] = buffer[i];
      }
      count += rbyte;
    }
    String xmlData = new String(xmldataByte, "UTF-8");
    System.out.println(xmlData);
    return xmlData;
  }

  /**
   * 批量创建订单
   * <p>
   * 适用于批量结算订单
   * <p>
   */
  public void createOrders(MyHttpRequest req, MyHttpResponse res) throws IOException {
    String userNote = "";
    int addressId = -1;
    String recordArray = "";
    BigDecimal totalPrice = null;
    try {
      // 买家留言
      userNote = req.getParameter("userNote");
      // 收获地址
      addressId = Integer.parseInt(req.getParameter("addressId"));
      // 购物车中的用于批量结算的产品数组,格式:[1,2,3]
      recordArray = req.getParameter("recordArray");
      // 前端用于结算时提交的总价
      totalPrice = BigDecimal.valueOf(Double.parseDouble(req.getParameter("totalPrice")));
    } catch (Exception e) {
      e.printStackTrace();
      res.failedFor302("参数错误!");
      return;
    }
    // 地址是否存在
    WebUserAddress userAddress = userAddressService.getUserAddress(addressId, req.getCurrentUser().getId());
    if (userAddress == null) {
      res.failed("收获地址不存在!");
      return;
    }
    // 参数校验
    Result validateResult = orderService.validateParams(recordArray, totalPrice, req.getCurrentUser().getId());
    if (!validateResult.getResult()) {
      res.failedFor302(validateResult.getMsg().toString());
      return;
    }
    try {
      res.setResult(this.orderService.createOrders(recordArray, totalPrice, addressId, userNote, req.getCurrentUser()));
    } catch (MyException e) {
      e.printStackTrace();
      res.failed("创建订单失败!");
    }
  }
}